import React, { Component, ReactChild, ReactChildren, ReactElement, ReactNode } from "react";
import { View, Text, Image, } from "@tarojs/components";
import { OsBadge } from 'ossaui'
import "./index.scss";
import Taro from "@tarojs/taro";

import img from "./images/vertical.png";
import { transformToRemOrRpx } from "../utils";

/**
 * @param onClick:()=>{return{index:numbner,text:string}}; | 点击tab
 * @param choOptionItem:()=>{};| 点击下拉列表的选项
 * @param customIcon:React.ReactChild;| 自定义小图标
 * @param showIcon:boolean;| 显示小图标
 * @param unified_allocation:boolean; | tab均匀分配
 * @param showNumberWord:number | 展示的字数
 * @param className:string | tabs容器的类名
 * 
 */


interface LgTabsProps extends LgTabsPropsTypeA, LgTabsPropsTypeB, LgTabsPropsCommon {

    default?: number;//默认选中第几个tab
    showNumberWord?: number;//tab上显示的字数限制

    unifiedAllocation?: boolean;//tab之间的距离是否相等 

    onClick?(index?: number, text?: string): void;//点击tab的时候会返回当前的tab下标和当前的tab名称
}
interface LgTabsPropsCommon {
    style?: React.CSSProperties;//常规样式
    className?: string;//常规使用的类名

    activeClass?: string;//选中tab中的文字类名
    activeSlideClass?: string;//选中tab中的分割线类名
}
interface LgTabsPropsTypeA extends LgTabsPropsCommon {
    unified_allocation?: boolean;//tab之间的距离是否相等
    customModule?: boolean;//

    tabsContainerClass?: string;//
}
interface LgTabsPropsTypeB extends LgTabsPropsCommon {

    showIcon?: boolean;//显示小图标,主要用于区分
    customIcon?: React.ReactChild | React.ReactElement;// 自定义小图标

    scrollIntoViewName?: string;//

    choOptionItem?(index?: number, text?: string): void;//点击返回当前展开列表的选项时返回当前的tab下标和当前的tab名称
}
export { LgTabs, LgTab, LgTabsA, LgTabsB };
class LgTabs extends Component<LgTabsProps, {}> {
    state = {};
    componentDidMount() { }
    componentDidShow() { }
    componentDidHide() { }
    componentDidCatchError() { }
    initDom(showIcon, unifiedAllocation, props): React.ReactChild | React.ReactElement {
        let _newDom: React.ReactChild | React.ReactElement;
        if (showIcon) {
            _newDom = <LgTabsB {...props} />;
        } else {
            if (unifiedAllocation) {
                _newDom = <LgTabsA {...props} unified_allocation />;
            } else {
                _newDom = <LgTabsA {...props} />;
            }
        }
        return _newDom;
    }
    render() {
        var props = this.props;
        let Dom = this.initDom(props.showIcon, props.unifiedAllocation, props);
        return <View className="container_tabs_tab">{Dom}</View>;
    }
}
interface LgTabsStateTypeA {
    currentChoIndex: number;//当前选中的下标
}
class LgTabsA extends Component<LgTabsProps, LgTabsStateTypeA> {
    constructor(props) {
        super(props);
        this.state = {
            currentChoIndex: this.props.default || 0,
        };
    }
    choTabItem(index, text) {
        this.setState({ currentChoIndex: index });
        this.props.onClick && this.props.onClick(index, text);
    }
    // 初始化Tab的切换数据和Dom
    initTab(oDom): { tabDom: React.ReactElement[] | React.ReactChild[], title: string[] } {
        let tabDom: React.ReactElement[] | React.ReactChild[];
        let that = this;
        let title: string[] = [];
        let currentChoIndex = that.state.currentChoIndex;
        if (!oDom) {
            return { tabDom: [], title }
        }
        if (oDom.length > 0) {
            tabDom = oDom.map((o, i) => {
                title.push(o.props.title);
                return (
                    <View
                        className="container_children_box"
                        style={{
                            display: that.state.currentChoIndex == i ? "block" : "none",
                            width: that.state.currentChoIndex == i ? "100%" : "0",
                        }}
                        key={i}
                    >
                        {o.props.children}
                    </View>
                );
            });
            tabDom = tabDom.splice(currentChoIndex, 1);
        } else {
            tabDom = oDom;
        }
        return { tabDom, title };
    }

    render() {
        var props = this.props;


        let { tabDom, title } = this.initTab(props.children);
        let unifiedAllocation = props.unified_allocation
            ? "unified_allocation"
            : "";
        return (
            <View className={"container_tabs " + (props.className || '') + ' ' + props.tabsContainerClass || ""} style={this.props?.style}>
                <View className={"lgTabs-container_tab " + unifiedAllocation}>
                    {title.map((o, i) => {
                        let titleText = o;
                        let currentChoIndex = this.state.currentChoIndex;
                        if (currentChoIndex > title.length - 1) {
                            currentChoIndex = title.length - 1;
                        }
                        let className =
                            i == currentChoIndex
                                ? "lgTab__active " + props.activeClass + ' ' || ""
                                : props.children[i].props.className + "";
                        let sliderClassName =
                            i == currentChoIndex
                                ? "lgTab__active_container " + props.activeSlideClass || ""
                                : "";

                        // console.log(o.length > (props.showNumberWord || 8))
                        if (o.length > (props.showNumberWord || 8)) {
                            titleText = o.slice(0, (props.showNumberWord || 8));
                            titleText = titleText + "...";
                            // console.log('dfasudhfujasdhfjkdashf ')
                        } else {
                            titleText = o
                        }
                        return (
                            <LgTab
                                title={titleText}
                                className={className}
                                sliderClassName={sliderClassName}
                                remindDom={props.children[i].props.remindDom}
                                choTabItem={() => this.choTabItem(i, o)}
                                key={i}
                            ></LgTab>
                        );
                    })}
                </View>
                {!props.customModule ? (
                    <View className="container_children" style={{}}>
                        {tabDom}
                    </View>
                ) : (
                    ""
                )}
            </View>
        );
    }
}
let _TabsId = 0;
interface LgTabsStateTypeB {
    currentChoIndex: number;// //点击当前的盒子信息
    showOption: boolean;// //是否展开下拉列表
    scrollIntoViewId: string | null;//
    scrollIntoView: string;//
    containerOptionWidth: string | number;//
    transLateX: number | string;//
    tabListDomData: any[] | null;// //tabs的dom节点信息
    overflowDom: any[] | null;// //滚动盒子的DOM节点信息
    LastMoveLength: number | null;// //上一次滑动的距离
    direction: number | null;//
    isOnClick: boolean;//
    touchMoveLength: number
}
class LgTabsB extends Component<LgTabsProps, LgTabsStateTypeB> {
    private currentChoIndex: number;//选中的tab
    private initHasChoItem: boolean;//选中的tab
    constructor(props) {
        super(props);
        this.currentChoIndex = 0;
        this.initHasChoItem = false;
        this.state = {
            currentChoIndex: this.props.default || 0, //点击当前的盒子信息
            showOption: false, //是否展开下拉列表
            scrollIntoViewId: null,
            scrollIntoView: "lgTab_container_",
            containerOptionWidth: "",
            transLateX: "0rem",
            tabListDomData: null, //tabs的dom节点信息
            overflowDom: null, //滚动盒子的DOM节点信息
            LastMoveLength: null, //上一次滑动的距离
            direction: null,
            isOnClick: false,
            touchMoveLength: 0
        };
    }
    queriedDom = false;
    moveLength = 0; //滑块已经滑动的距离px
    tabsId = "tabs_container_box_Only" + _TabsId++;
    startX = 0;
    endX = 0;
    maxMoveItemWidth = null;//tab所有的宽度
    maxMoveContainerWidth = null;;//tabs容器的宽度
    maxMoveLeftWidth = 0;//往左滑动的最大宽度 = maxMoveContainerWidth - maxMoveItemWidth
    maxOverflowMoveLeftWidth = 0;
    onStart(event) {
        this.startX =
            event.changedTouches[0].screenX || event.changedTouches[0].pageX;
        this.setState({ isOnClick: true });
    }
    onMove(event) {
        this.setState({ isOnClick: false });
        let state = this.state;
        let transLateX = state.transLateX;
        let LastMoveLength: number = this.state.LastMoveLength as number;
        // 手指点击时的X坐标
        let startX = this.startX;

        // 滑动结束时滑块最后的距离
        let endX = this.endX;
        // 滑动的到左边的最大距离
        let maxMoveLeft = this.maxMoveLeftWidth;
        // 手指横向滑动的X坐标
        let eventMoveX =
            event.changedTouches[0].screenX || event.changedTouches[0].pageX;
        // 手指横向滑动的距离
        let direction = startX - eventMoveX > 0 ? +1 : -1;
        let touchMoveLength = Math.abs(startX - eventMoveX);
        if (touchMoveLength < 5) {
            return;
        }
        if (LastMoveLength >= maxMoveLeft && direction > 0) {
            this.moveLength = Math.abs(maxMoveLeft);
            this.setState({
                transLateX: transformToRemOrRpx(-maxMoveLeft.toFixed(2)),
            });
            return;
        }

        let moveLength = 0;
        if (direction > 0 && LastMoveLength < maxMoveLeft) {
            // 左滑动
            moveLength = LastMoveLength + touchMoveLength;
        } else {
            // 右滑动
            moveLength = LastMoveLength - touchMoveLength;

            if (moveLength < 0) {
                moveLength = 0;
            }
        }
        let slideFastMve: number = moveLength.toFixed(2) as any;
        transLateX = transformToRemOrRpx(-slideFastMve);
        this.setState({
            touchMoveLength,
            transLateX,
            direction,
        });
        this.moveLength = Math.abs(slideFastMve);
    }
    onEnd(event) {
        if (this.state.isOnClick) {
            return;
        }

        let state = this.state;
        if (this.moveLength >= this.maxMoveLeftWidth) {
            this.setState({
                LastMoveLength: this.maxMoveLeftWidth, //上一次滑块已经滑动的距离
            });
        } else {
            state.tabListDomData?.forEach((o, i) => {
                if (this.moveLength > o.left && this.moveLength < o.right) {
                    if (this.state.direction as number > 0) {
                        this.moveLength = o.right;
                    } else {
                        this.moveLength = o.left;
                    }
                }
            });
            this.setState({
                LastMoveLength: this.moveLength, //上一次滑块已经滑动的距离
                transLateX: transformToRemOrRpx(-this.moveLength),
            });
        }
        if (
            Math.abs(parseFloat(this.state.transLateX as any)) >
            parseFloat(transformToRemOrRpx(this.maxMoveLeftWidth))
        ) {
            this.setState({
                transLateX: transformToRemOrRpx(-this.maxMoveLeftWidth),
            });
        }
    }
    componentDidShow() {
        this.queryDom()
    }
    componentDidMount() {
        this.queryDom();
    }
    componentWillUnmount() {
        this.queriedDom = true;
    }
    queryDom(resetIndex?: boolean) {
        if (this.queriedDom) { return }
        this.maxMoveItemWidth = null;
        this.maxMoveContainerWidth = null;
        this.initHasChoItem = false;
        let query = Taro.createSelectorQuery(), that = this;;
        setTimeout(() => {
            // 查询所有的tab
            query.selectAll(`#${this.tabsId} .slide_tab_item`)
                .boundingClientRect((res: any) => {
                    if (!res.length) { that.maxMoveLeftWidth = 0; that.setState({ tabListDomData: [], }); this.queryDom(); return }
                    that.queriedDom = true;
                    that.maxMoveItemWidth = res[res.length - 1].right;
                    that.setState({ tabListDomData: res, }, () => { that.intMaxMoveWidth() });
                })
                .exec(() => {
                    setTimeout(() => {
                        query.selectAll(`#${this.tabsId}`)
                            .boundingClientRect((res: any) => {
                                if (!res.length) { this.queryDom(); return }
                                that.queriedDom = true;
                                let maxMoveLeftWidth = 0;
                                res.forEach(o => {
                                    maxMoveLeftWidth += o.width
                                });
                                that.maxMoveContainerWidth = maxMoveLeftWidth as any;
                                // 如果容器的宽度大于tab所有的宽度时将最大移动的宽度设置为0
                                if (that.maxMoveLeftWidth < 0) { that.maxMoveLeftWidth = 0 };
                                that.setState({ overflowDom: res, }, () => {
                                    that.intMaxMoveWidth(resetIndex)
                                });
                            })
                            .exec(() => { });
                    }, 200);
                });
        }, 200);

    }
    intMaxMoveWidth(resetIndex?: boolean) {
        if (this.maxMoveItemWidth != null && this.maxMoveContainerWidth !== null) {
            this.maxMoveLeftWidth = this.maxMoveItemWidth - this.maxMoveContainerWidth;
            if (this.maxMoveLeftWidth < 0) { this.maxMoveLeftWidth = 0 }
            let currentChoIndex = this.state.currentChoIndex;
            if (currentChoIndex && currentChoIndex > (this.props.children as React.ReactElement[]).length - 1) {
                currentChoIndex = (this.props.children as React.ReactElement[]).length - 1;
            } else if (currentChoIndex <= 0) {
                currentChoIndex = 0
            }
            if (!this.initHasChoItem) {
                this.initHasChoItem = true;
                this.choTabItem(resetIndex ? 0 : currentChoIndex, "", false);
            }
        }
    }
    choTabItem(index: number, text?: string, trigger: boolean = true) {
        let i: number = index || 0;
        let tabListDomData: any[] = this.state.tabListDomData as any[];
        if (!tabListDomData.length) {
            return
        }
        let transLateX = 0;
        tabListDomData.forEach((o, i) => {
            if (i < index - 1) {
                transLateX += o.width
            }
        })
        if (transLateX > this.maxMoveLeftWidth) {
            transLateX = this.maxMoveLeftWidth;
        }
        transLateX = Math.abs(transLateX);
        (transLateX as any) = transformToRemOrRpx(-transLateX);
        this.currentChoIndex = index;
        this.setState({ currentChoIndex: index as number, transLateX, showOption: false });
        trigger && this.props.onClick && this.props.onClick(index, text);
    }
    // 初始化Tab的切换数据和Dom
    initTab(oDom): { tabDom: React.ReactElement[], title: string[] } {
        let tabDom: React.ReactElement[] = [];
        let that = this;
        let title = [];
        if (!oDom) { return { tabDom: [], title } }
        let currentChoIndex = that.currentChoIndex;
        if (oDom.length > 0) {
            tabDom = oDom.map((o: any, i) => {
                title.push(o.props.title as never);
                return (
                    <View className="" key={i} style={{ display: that.currentChoIndex == i ? "block" : "none", width: that.currentChoIndex == i ? "100%" : "0", height: "100%", }}>{o.props.children}</View>
                );
            });
            // 将自定义的Dom抛出展示
            tabDom = tabDom.splice(currentChoIndex, 1);
        } else {
            tabDom = oDom;
        }
        return { tabDom, title };
    }
    openOption() { this.setState({ showOption: !this.state.showOption, }); }
    showIconDom(iconDOM) {
        let dom = (<View className="container_icon" onClick={this.openOption.bind(this)}><View className="icon-b01801 icon-tabs_style"></View></View>);
        if (iconDOM) { dom = (<View className="container_icon" onClick={this.openOption.bind(this)}>{iconDOM}</View>); }
        return dom;
    }
    choTabOptionItem(index, value) {
        let tabListDomData: any[] = this.state.tabListDomData as any[];
        if (!tabListDomData.length) { return }
        let transLateX = 0;
        tabListDomData.forEach((o, i) => { if (i < index - 1) { transLateX += o.width } })
        if (transLateX > this.maxMoveLeftWidth) { transLateX = this.maxMoveLeftWidth; }
        (transLateX as any) = transformToRemOrRpx(-transLateX);
        this.currentChoIndex = index;
        this.setState({ currentChoIndex: index, transLateX, showOption: false });
        this.props.choOptionItem && this.props.choOptionItem(index, value);
    }
    componentWillReceiveProps(nextProps: LgTabsProps & { children?: ReactNode }) {
        // console.log(this.props.children);
        // if (this.props != nextProps) { this.queriedDom = false; this.queryDom(); }
        let doQuery = false
        if (this.props.children != nextProps.children) {
            if (typeof this.props.children === "undefined" || typeof nextProps.children === "undefined") {
                doQuery = true
            } else {
                let oldChildrenTitles = (this.props.children as ReactElement<LgTabProps>[]).map(child => child.props.title)
                let newChildrenTitles = (nextProps.children as ReactElement<LgTabProps>[]).map(child => child.props.title)
                if (JSON.stringify(oldChildrenTitles) !== JSON.stringify(newChildrenTitles)) { doQuery = true }
            }
        }
        if (doQuery) { this.queriedDom = false; this.queryDom(true); }
    }
    render() {
        let state = this.state;
        var props = this.props;
        let { tabDom, title } = this.initTab(props.children);
        let iconDom = this.showIconDom(props.customIcon);
        // console.log(props, 'props');
        return (
            <View className={"container_tabs " + (props.className || '') + ' ' + (props.tabsContainerClass || "")} style={this.props?.style}>
                <View className="container_tabs_header_box">
                    <View
                        className="lgTabs-container_tab" id={this.tabsId}
                        onTouchStart={this.onStart.bind(this)}
                        onTouchMove={this.onMove.bind(this)}
                        onTouchEnd={this.onEnd.bind(this)}
                    >
                        <View className="container_scrollView" style={{ transform: "translateX(" + state.transLateX + ")" }}>
                            {title.map((o, i) => {
                                let titleText = o;
                                let currentChoIndex = this.currentChoIndex;
                                if (currentChoIndex > title.length - 1) { currentChoIndex = title.length - 1; }
                                let className = i == currentChoIndex ? "slide_tab_item lgTab__active" : "slide_tab_item";
                                let sliderClassName = i == currentChoIndex ? "lgTab__active_container" : "";
                                if (o.length > (props.showNumberWord || 8)) {
                                    titleText = o.slice(0, (props.showNumberWord || 8));
                                    titleText = titleText + "...";
                                } else { titleText = o }
                                return (
                                    <LgTab
                                        title={titleText}
                                        className={className}
                                        count={props.children[i].props.count}
                                        sliderClassName={sliderClassName}
                                        choTabItem={() => this.choTabItem(i, o)}
                                        key={i}
                                        showIcon
                                        id={"lgTab_container_" + (props.scrollIntoViewName || "default") + i}
                                    ></LgTab>
                                );
                            })}
                        </View>
                    </View>
                    <View style={{ display: !props.customModule ? "block" : "none", }} className="container_option_icon_box">
                        <Image className="container_option_icon_split" style={{ width: '1px', height: '15px', backgroundColor: '#ffffff', opacity: '.36' }} />
                        {iconDom}
                        {/* <View className={this.state.showOption ? "container_option" : "container_option container_option_close"}>
                            <View className="container_option_box">
                                {title.map((o, i) => {
                                    let active = this.currentChoIndex == i ? "option_item-active" : "";
                                    return (<View key={i} className={"option_item " + active} onClick={() => { this.choTabOptionItem(i, o); }}>{o}</View>);
                                })}
                            </View>
                        </View> */}
                    </View>
                </View>
                {!props.customModule ? (<View className="container_children">{tabDom}</View>) : ("")}
            </View>
        );
    }
}
interface LgTabProps {
    title?: string;//

    className?: string;//
    sliderClassName?: string;//
    id?: string;//
    index?: number;//
    showIcon?: boolean;//
    remindDom?: any;
    count: number;
    choTabItem?(): void;//
}
class LgTab extends Component<LgTabProps, {}> {
    render() {
        var props = this.props;
        return (
            // <OsBadge type='info' info={props.count}>
            <View
                className={"lgTab_container " + props.className}
                data-index={props.index}
                onClick={props.choTabItem}
            >
                {
                    this.props.remindDom
                }
                <Text className="lgTab_container_text">
                    <Text>{props.title}</Text>
                    {
                        props.count > 0 ?
                            <Text className="lgTab_count">{props.count}</Text> : ""
                    }
                </Text>
                <Image
                    className="vertical_icon"
                    style={{ display: props.showIcon ? "block" : "none" }}
                // src={require("./images/vertical.png")}
                />
                <View className={props.sliderClassName}></View>

            </View>
            // </OsBadge>
        );
    }
}
